// echo aux function only, should not compile alone.
// -r:"../../Backend/System.IO.FileSystem.dll"

//! 编译方法，目前来说只能是自己改上面那行字，把缺的东西都补齐，之后送命令提示符或者用python脚本编译。
//! windows就是一坨shit……连通配符都不支持……不然我至少能写出类似 dotnet C:\Program Files\dotnet\sdk\*\Roslyn\bincore\csc.dll 这样的语法

// -r:"../../The Scroll of Taiwu_Data/Managed/Mono.Cecil.dll" -r:"../../The Scroll of Taiwu_Data/Managed/System.Core.dll"   -r:"../../The Scroll of Taiwu_Data/Managed/System.Composition.AttributedModel.dll" -r:"../../Backend/System.Runtime.dll"
/**
 *  Everyone's Unity Game Plugin
 *  Copyright (C) 2022 Neutron3529
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
//! 这是一个自带文档注释的Mod，虽然代码很shit，但里面有不少注释，或许会对之后准备玩过月逻辑的人有帮助。
//! 所有文档注释会用//!开头，请注意搜索
//! 首先是前后端，前端对后端的调用会先被塞进 ProcessMethodCall，之后分发给对应domain的CallMethod，由CallMethod进行进一步的分发。借助这一点，我们可以快速找到前端调用究竟是在使用哪个函数。
using System;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Collections.Generic;
using static Utils.Logger;

using Config.EventConfig;
using GameData.Domains.TaiwuEvent;
using GameData.Domains.TaiwuEvent.Enum;

namespace Neutron3529.ChaosEvents {
    public partial class ChaosEvents : EventPackage {
        public 武师.武师 E03(){
            var o=new 武师.武师();
            {
                var taiwuEvent = GameData.Domains.DomainManager.TaiwuEvent.GetEvent("fb38f657-6ed0-41e4-a0c2-c82afb49762f"); // @人物互动-恩义互动
                var lst=taiwuEvent.EventConfig.EventOptions.ToList();
                lst.Insert(lst.Count-1, o.EventOptions[0]);
                lst.Insert(lst.Count-1, o.EventOptions[1]);
                taiwuEvent.EventConfig.EventOptions=lst.ToArray();
            }
            return o;
        }
    }
    namespace 武师 {
        public class 武师 : EventItem {
            public 武师() :base("Prof.武师", "70b4d45d-ba15-423d-b94e-b40e348eb9c3", "{0}听太吾竟如此热情\n吓得双眼一闭，两腿一蹬\n直挺挺倒在了地上……"){
                this.EventOptions = new TaiwuEventOption[4];
                for(int i=0;i<this.EventOptions.Length;i++){
                    var op=new TaiwuEventOption {
                        OptionKey = "Option_352903"+i.ToString("02"),
                        OnOptionSelect = new Func<string>(this.OnOptionSelect(i)),
                        OnOptionVisibleCheck = new Func<bool>(this.OnCheckOptionCondition(i)),
                        OnOptionAvailableCheck = new Func<bool>(this.OnCheckEventCondition),
                        GetReplacedContent = new Func<string>(this.Desc(i)),
                        GetExtraFormatLanguageKeys = new Func<List<string>>(this.GetExtraFormatLanguageKeys)
                    };
                    this.EventOptions[i]=op;
                }
            }
            public override string EventContent()=>string.Format(this.content, Name(this.ArgBox.GetCharacter("CharacterId")));
            private Func<bool> OnCheckOptionCondition(int index){
                switch(index){
                    case 0:
                    case 1:return ()=> {
                        int idx=0;
                        if(!this.EventOptions[index].ArgBox.Get("NeutronFlag",ref idx)){
                            var pd=GameData.Domains.TaiwuEvent.EventHelper.EventHelper.GetCurrentProfessionData();
                            if(pd!=null && pd.TemplateId == 3 && pd.IsSkillUnlocked(1)){
                                return this.EventOptions[index].ArgBox.GetCharacter("CharacterId") != null;
                            }
                        }
                        return false;
                    };
                    default: return ()=>{
                        var pd=GameData.Domains.TaiwuEvent.EventHelper.EventHelper.GetCurrentProfessionData();
                        return pd!=null && pd.TemplateId == 3 && this.EventOptions[index].ArgBox.GetCharacter("CharacterId")!=null;
                    };
                }
            }
            private unsafe Func<string> OnOptionSelect(int index){
                switch(index){
                    case 0: return ()=> {
                        this.EventOptions[index].ArgBox.Set("NeutronFlag",(int)0);
                        return "70b4d45d-ba15-423d-b94e-b40e348eb9c3"; // 重入本事件（这是乱入本事件用的选项）并借助NeutronFlag的存在而隐去选项1
                    };
                    case 1: return ()=> {
                        this.EventOptions[index].ArgBox.Set("NeutronFlag",(int)1);
                        return "70b4d45d-ba15-423d-b94e-b40e348eb9c3"; // 重入本事件（这是乱入本事件用的选项）并借助NeutronFlag的存在而隐去选项2
                    };
                    case 2:return ()=> {
                        int idx=0;
                        this.EventOptions[index].ArgBox.Get("NeutronFlag", ref idx);
                        this.EventOptions[index].ArgBox.Remove<int>("NeutronFlag");
                        var ArgBox=this.EventOptions[index].ArgBox;
                        var targetChar = ArgBox.GetCharacter("CharacterId");
                        var selfChar = ArgBox.GetCharacter("RoleTaiwu");
                        var ideal=targetChar.GetIdealSect();
                        var currDate = GameData.Domains.DomainManager.World.GetCurrDate();
                        var location = selfChar.GetLocation();
                        var lifeRecordCollection = GameData.Domains.DomainManager.LifeRecord.GetLifeRecordCollection();
                        var cname=Name(this.ArgBox.GetCharacter("CharacterId"));
                        // logwarn($"idx={idx}");
                        if(idx==0){// 灌顶突破功法
                            var ts=new List<short>(targetChar.GetLearnedCombatSkills());
                            ts.RemoveAll((x)=>!GameData.Domains.DomainManager.CombatSkill.GetElement_CombatSkills(new GameData.Domains.CombatSkill.CombatSkillKey(targetChar.GetId(), x)).CanBreakout());
                            if(ts.Count>0){
                                var breakingDemandAction = new GameData.Domains.Character.Ai.GeneralAction.StudyDemand.BreakingDemandAction {
                                    AgreeToRequest = true,
                                    CombatSkillTemplateId = ts[0]
                                };
                                if (breakingDemandAction.CheckValid(targetChar, selfChar)) {
                                    GameData.Domains.TaiwuEvent.EventHelper.EventHelper.ApplyGeneralActionChanges(breakingDemandAction, targetChar, selfChar);
                                }
                        // logwarn($"idx={idx}, before return successful");
                                return Goto($"经过一番鸡飞狗跳\n{cname}终究是突破了{Config.CombatSkill.Instance[ts[0]].Name}的玄关","（如此甚好……）");
                            }
                            return Goto($"经过一番鸡飞狗跳\n太吾发觉{cname}并没有任何可以突破的功法","（只好如此……）");
                        } else {//随缘+功法
                            var tws=new List<short>(selfChar.GetLearnedCombatSkills());
                            var ts=targetChar.GetLearnedCombatSkills();
                            tws.RemoveAll((x)=>ts.Contains(x));
                            if(tws.Count==0){
                        // logwarn($"idx={idx}, before early return failed");
                                return Goto($"经过一番鸡飞狗跳\n太吾发觉{cname}上知天文下知地理已无任何可以传授的功法了","（只好如此……）");
                            } else if (tws.Exists((x)=>Config.CombatSkill.Instance[x].SectId==ideal)){
                                tws.RemoveAll((x)=>Config.CombatSkill.Instance[x].SectId!=ideal);
                            }
                            for(int i=0;i<8;i++){
                                if(tws.Exists((x)=>Config.CombatSkill.Instance[x].Grade==i)){
                                    tws.RemoveAll((x)=>Config.CombatSkill.Instance[x].Grade!=i);
                                    targetChar.LearnNewCombatSkill(this.context, tws[0], 0, 0);
                                    lifeRecordCollection.AddRequestInstructionOnCombatSkillSucceed(selfChar.GetId(), currDate, targetChar.GetId(), location, 10, tws[0], 1);
                        // logwarn($"idx={idx}, before return successful");
                                    return Goto($"经过一番鸡飞狗跳\n{cname}终究是学会了{Config.CombatSkill.Instance[tws[0]].Name}","（如此甚好……）");
                                }
                            }
                            return Goto($"经过一番鸡飞狗跳\n太吾发觉{cname}上知天文下知地理已无任何可以传授的功法了","（只好如此……）");
                        }
                    };
                    default: return ()=>string.Empty;
                }
            }
            public override Func<string> Desc(int i){
                switch(i){
                    case 0:
                        return ()=>"（咬牙灌顶……）";
                    case 1:
                        return ()=>"（随缘教学……）";
                    case 2:
                        return ()=>"（不要害怕……）";
                    case 3:
                        return ()=>"不过教你功法而已，又不是给你煎饼，何至于斯？";
                    default: return ()=>string.Empty;
                }
            }
        }
    }
}
